#include "errdatafilereader.h"

#pragma comment(lib, "opencv_core249.lib")
#pragma comment(lib, "opencv_highgui249.lib")

//inline QString  CS2QS(CString cs) { return  QString::fromWCharArray((LPCTSTR)cs, cs.GetLength()); }
inline CString  QS2CS(QString qs) { return  CString(qs.toStdWString().c_str()); }


class nItem
{
public:
    nItem()
    {

    }
    ~nItem()
    {
        if( pDib )
            pDib->Release();
        if( pTypeDib )
            pTypeDib->Release();
    }

    bool saveOriImg(const QString &path,int q=100)
    {
        if(isSerializeJpg)
        {
            return pDib->SaveToJPGFile(QS2CS(path),q);
        }else
            return false;
    }
    bool markImg(const QString &path,const QString &destpath)
    {
        cv::Mat img = cv::imread(path.toStdString());
        for(auto it : rects)
        {
            cv::rectangle(img, it, cv::Scalar(0, 0, 255),1, 1,0);
            cv::imwrite(destpath.toStdString(),img);
        }
        return true;
    }

    int pcbnumber = -1;
    int index = -1;
    BYTE isTrueErr = false;
    BYTE      nType = -1;  //类型
    IDib*      pDib = nullptr;  //缺陷图像
    QVector<cv::Rect> rects;

    bool isSerializeJpg = false;

    CPoint     point;
    CPoint     ptImage;
    IDib*      pTypeDib = nullptr;
};


class ITEM
{
public:
    ITEM()
    {
        //         pRcs = NULL;
        pDib = nullptr;
        pTypeDib = NULL;
        ptImage = CPoint(-1,-1);//INVALID_POINT;
        ptUnitNo = CPoint(-1,-1);
        nSamePosSign = 0;
        bTrueErr = false;
    }
    ~ITEM()
    {
        //         if( pRcs )
        //            delete pRcs;
        if( pDib )
            pDib->Release();
        if( pTypeDib )
            pTypeDib->Release();
    }
    CPoint     point;
    CPoint     ptImage;
    //     CRectArray*   pRcs; //位置
    BYTE       nType;  //类型
    IDib*      pDib;  //缺陷图像
    IDib*      pTypeDib;

    CPoint     ptUnitNo; // 临时数据
    BYTE       nSamePosSign; // 固定点
    BYTE        bTrueErr;
};

BOOL CErrDataBase_Serialize(CArchive& ar, BOOL bCompress)
{
    //LOG() ;
    // 文件头
    CString sSign("Kaima pcb-avi-err File.");

    //LOG() ;
    {
        CString s;
        //LOG() ;
        ar >> s;
        //LOG() ;
        //LOG() << s  << "  " << sSign << " " << (s == sSign) ;
        if( s != sSign )
            return FALSE;
    }

    //LOG() ;

    UINT nCurVersion = 30, nVersionLoad;
    ar >> nVersionLoad;
    if( nCurVersion < nVersionLoad)
        //if( !IBaseTool::Serialize_Version(ar, nCurVersion, nVersionLoad) )
        return FALSE;

    //LOG() << "nVersionLoad " << nVersionLoad ;

    {
        if( nVersionLoad > 23 )
            ar >> bCompress;

        //LOG() << "bCompress "  << (bool)bCompress ;
        // 内容
        int nErrCount;
        ar >> nErrCount;
        //LOG() << "nErrCount " << nErrCount ;
        //       m_aItems.SetSize( nErrCount );

        BYTE bHas;
        //       CRectArray* pRects;
        CRect rc;
        int nRectCount, iRect;
        ITEM *pItem;
        for(int iErr = 0; iErr < nErrCount; iErr++)
        {
            pItem = new ITEM;
            //           m_aItems[ iErr ] = pItem;
            ar >> pItem->point;
            if( nVersionLoad > 22 )
                ar >> pItem->ptImage;
            else
                pItem->ptImage = pItem->point;

            // Dib
            ar >> bHas;
            //LOG() << "Dib bHas "  << (bool)bHas << " bCompress " << (bool)bCompress ;
            if( bHas )
            {
                pItem->pDib = CreateIDib();
                if( bCompress )
                {
                    if(pItem->pDib->SerializeJpg(ar))
                    {
                        CString filename;
                        filename.Format(_T("C:\\Users\\richa\\Documents\\Projects\\PCBHelper\\Release\\10_b_%d.jpg"),iErr);
                        pItem->pDib->SaveToJPGFile(filename,100);
                    }
                }
                else
                    pItem->pDib->Serialize(ar);
            }
            else
                pItem->pDib = NULL;

            // TypeDib
            if( nVersionLoad > 8 )
            {
                ar >> bHas;
                //LOG() << "TypeDib bHas "  << (bool)bHas ;
                if( bHas )
                {
                    pItem->pTypeDib = CreateIDib();// CreateINoPaintDib();
                    pItem->pTypeDib->Serialize(ar);
                }
                else
                    pItem->pTypeDib = NULL;
            }

            // rects
            ar >> nRectCount;
            //LOG() << "nRectCount "  << nRectCount ;
            if( nRectCount > 0 )
            {
                //              pItem->pRcs = new CRectArray;
                //              pRects = pItem->pRcs;
                //              pRects->SetSize( nRectCount );
                for(iRect = 0; iRect < nRectCount; iRect++)
                {
                    ar >> rc;
                    //                  pRects->SetAt( iRect, rc );
                    //LOG() << "Rects i " << iRect << " size "  << rc.Width() << "x" << rc.Height() << " left point " << rc.TopLeft().x << " " << rc.TopLeft().y ;
                }
            }
            //           else
            //              pItem->pRcs = NULL;

            ar >> pItem->nType;


            //LOG() << "-----------------------------------------" ;

            //LOG() << "缺陷位置: x"  << rc.TopLeft().x << " y" << rc.TopLeft().y << " 大小 " <<  rc.Width() << "*" << rc.Height()  ;
            //           //LOG() << "缺陷类型: " << (int)pItem->nType << " " << getTypeString(pItem->nType) <<  endl;

            //LOG() << "-----------------------------------------" ;
            delete pItem;
            pItem = nullptr;
        }

        // 统计
        int nCount = 0;
        if( nVersionLoad > 25 )
        {
            ar >> nCount;
            //LOG() << "统计 nCount "  << nCount  << " m_aTotals.GetSize() " <<nCount;
            //           if( nCount > m_aTotals.GetSize() )
            //              m_aTotals.SetSize( nCount );
        }
        else
        {
            if( nVersionLoad < 2 )
                nCount = 12;
            else if( nVersionLoad < 3 )
                nCount = 13;
            else if( nVersionLoad < 5 )
                nCount = 14;
            else if( nVersionLoad < 6 )
                nCount = 15;
            else if( nVersionLoad < 8 )
                nCount = 16;
            else if( nVersionLoad < 10 )
                nCount = 27;
            else if( nVersionLoad < 11 )
                nCount = 28;
            else if( nVersionLoad < 12 )
                nCount = 29;
            else if( nVersionLoad < 14 )
                nCount = 30;
            else if( nVersionLoad < 15 )
                nCount = 31;
            else if( nVersionLoad < 16 )
                nCount = 32;
            else if( nVersionLoad < 17 )
                nCount = 33;
            else if( nVersionLoad < 18 )
                nCount = 34;
            else if( nVersionLoad < 19 )
                nCount = 35;
            else if( nVersionLoad < 20 )
                nCount = 36;
            else if( nVersionLoad < 23 )
                nCount = 37;
            else
                nCount = 38;
        }
        int typex;
        for(int iType = 0; iType < nCount; iType++)
        {
            ar >>typex;// m_aTotals[ iType ];
            //LOG() << "iType index " << iType << " value " <<typex;
        }
        float             m_fCarAngle;
        CSize             m_szCarOffset;
        CSize             m_szAdjustOffset;
        float             m_fPrecision;
        int               m_iScanCol;
        BOOL              m_bPcbTop;
        BOOL              m_bTimeOut;
        BOOL              m_bTryTest;
        CString              m_sPlNo;
        int               m_nPcbNo;

        // 附带信息
        if( nVersionLoad > 0 )
        {
            ar >> m_szAdjustOffset;
            if( nVersionLoad > 12 )
                ar >> m_fPrecision;
            else
                m_fPrecision = 0;
            ar >> m_iScanCol;
            if( nVersionLoad > 3 )
                ar >> m_sPlNo;
            else
                m_sPlNo = "";
            ar >> m_nPcbNo;
            ar >> m_bPcbTop;
            ar >> m_bTimeOut;

            //LOG() <<  "附加信息 "<< "m_szAdjustOffset " << m_szAdjustOffset.cx << "x" << m_szAdjustOffset.cy
            //                   << " m_fPrecision " << m_fPrecision << " m_iScanCol " << m_iScanCol
            //                   << " m_sPlNo " << m_sPlNo << " m_nPcbNo " << m_nPcbNo
            //                   << " m_bPcbTop " << (bool)m_bPcbTop << " m_bTimeOut " <<(bool)m_bTimeOut  ;
        }
        else
        {
            m_szAdjustOffset = CSize(0, 0);
            m_fPrecision = 0;
            m_iScanCol = -1;
            m_sPlNo = "";
            m_nPcbNo = 0;
            m_bPcbTop = true;
            m_bTimeOut = false;
        }
        if( nVersionLoad > 6 )
            ar >> m_bTryTest;
        else
            m_bTryTest = false;

        //LOG() <<  "m_bTryTest "<< (bool)m_bTryTest ;
        if( nVersionLoad > 21 )
        {
            ar >> m_fCarAngle;
            ar >> m_szCarOffset;
        }
        else
        {
            m_fCarAngle = 0;
            m_szCarOffset = CSize(0, 0);
        }

        //LOG() <<  "m_fCarAngle "<< m_fCarAngle << " m_szCarOffset " << m_szCarOffset.cx << "x" << m_szCarOffset.cy ;

        CString              m_sJob;
        BYTE              m_nPlaceType;
        if( nVersionLoad > 26 )
        {
            ar >> m_sJob;
            ar >> m_nPlaceType;
        }
        //LOG() <<  "m_sJob "<< m_sJob << " m_nPlaceType " << m_nPlaceType ;

        int               m_iUnitPadErr;
        if( nVersionLoad > 24 )
        {
            int nUnitPadCount;
            ar >> nUnitPadCount;

            //LOG() <<  "nUnitPadCount "<< nUnitPadCount  ;

            BYTE tmp;
            //           m_aUnitPadResults.SetSize( nUnitPadCount );
            for(int iUnitPad = 0; iUnitPad < nUnitPadCount; iUnitPad++)
            {
                ar >> tmp;

                //LOG() <<  "index "<< iUnitPad << " value "<< tmp;
            }
            ar >> m_iUnitPadErr;
            //LOG() <<  "m_iUnitPadErr "<< m_iUnitPadErr  ;
        }
        else
        {
            //           m_aUnitPadResults.RemoveAll();
            m_iUnitPadErr = -1;
        }
        CString              m_sDecode;
        if( nVersionLoad > 29 )
            ar >> m_sDecode;

        //LOG() <<  "m_sDecode "<< m_sDecode  ;

        // 附带多片
        if( nVersionLoad > 20 )
        {
            int nMultiTest;
            ar >> nMultiTest;
            //LOG() <<  "附带多片 nMultiTest  "<< nMultiTest  ;
            //CErrDataBase* pErrData;
            for(int i = 0; i < nMultiTest; i++)
            {
                //pErrData = CreateErrData();
                //m_aMultiTestErrDatas.Add( pErrData );

                //LOG() <<  "附带多片 index ------------------------------------- "<< i  ;
                if( !CErrDataBase_Serialize(ar, bCompress))
                    //if( !pErrData->Serialize(ar, bCompress) )
                    return FALSE;
            }
        }

        int m_iMultiTest;
        if( nVersionLoad > 28 )
            ar >> m_iMultiTest;

        //LOG() <<  "m_iMultiTest "<< m_iMultiTest ;

        if( nVersionLoad > 27 )
        {
            double f;
            int nDetailCount;
            ar >> nDetailCount;
            //           m_aDetailLineWidths.SetSize( nDetailCount );
            //LOG() <<  "nDetailCount "<< nDetailCount ;
            for(int iDetail = 0; iDetail < nDetailCount; iDetail++)
            {
                ar >> f;
                //              m_aDetailLineWidths[ iDetail ] = f;
                //LOG() <<  "index "<< iDetail << " value "<< f ;
            }
        }
    }
    return TRUE;
}


ErrDataFileReader::ErrDataFileReader(const QString &errDataFile)
{
    items.clear();
    if(QFile::exists(errDataFile))
    {
        m_FileErr = new CFile;
        auto b = m_FileErr->Open(QS2CS(errDataFile),CFile::modeRead);

        if(b == false)
            return;
        m_arErr = new CArchive(m_FileErr,CArchive::load);
        errFile = errDataFile;

        auto xFile = errDataFile + "_True";
        if(QFile::exists(xFile))
        {
            m_FileTrue = new CFile;
            m_FileTrue->Open(QS2CS(xFile),CFile::modeRead);
            if(b == false)
                return;
            m_arTrue = new CArchive(m_FileTrue,CArchive::load);
            trueFile = xFile;
        }

        dataPath = QFileInfo(errDataFile).path();
        hasError = false;
    }
}

void ErrDataFileReader::readItems()
{
    if(hasError)
        return;
    errDataBaseSerialize();
}

void ErrDataFileReader::readTrue()
{
    if(hasError)
        return;
    errTrueSerialize();
}

QPair<QString, QStringList> ErrDataFileReader::saveOutPutFile(int workmode, bool checkTF, const QString &outpath, const QString &inpath)
{
    QStringList res;

//    LOG() << dataPath << outpath << inpath;
    auto newDataPath = outpath + dataPath.remove(inpath);
    QDir d;
    if(d.mkpath(newDataPath) == false)
    {
        return QPair<QString, QStringList>(); //创建失败
    }
    if(workmode == 1)
    {
        d.mkpath(newDataPath + "/ori");
    }else if(workmode == 2)
    {
        d.mkpath(newDataPath + "/mark");
    }else{
        d.mkpath(newDataPath + "/ori");
        d.mkpath(newDataPath + "/mark");
    }

    while (!items.isEmpty()) {
         auto item = items.takeFirst();
         auto of = QString("%1_%2_%3_%4").arg(pcbNumber).arg(isTop?"t":"b").arg(item->index).arg(item->nType);

         if(checkTF)
         {
             of += (item->isTrueErr?"_T":"_F");
         }
         of+= ".jpg";

         auto f = newDataPath + + "/ori/" + of;
         auto fmark = newDataPath + + "/mark/" + of;

         if(workmode == 1)
         {
             item->saveOriImg(f);
         }else if(workmode == 2)
         {
             item->saveOriImg(fmark);
             item->markImg(fmark,fmark);
         }else{
             item->saveOriImg(f);
             item->markImg(f,fmark);
         }

         QStringList sigle;
         //添加文件名
         sigle.append(of);

         //添加板号
         sigle.append(this->pcbNumber);
         sigle.append(this->isTop?"T":"B");
         sigle.append(QString::number(item->index));
         sigle.append(QString::number(item->nType));

         //缺陷坐标 和 大小
         QString sizes,leftTop;
         for(auto it : item->rects)
         {
             leftTop += QString("%1*%2 | ").arg(it.x).arg(it.y);
             sizes += QString("%1*%2 | ").arg(it.width).arg(it.height);
         }
         sigle.append(leftTop);
         sigle.append(sizes);
         sigle.append(item->isTrueErr?"T":"F");

         res.append(sigle.join(","));
         delete item;
     }
     return qMakePair(newDataPath,res);
}

QPair<QString,QStringList> ErrDataFileReader::saveOutPutFile(int workmode, bool checkTF)
{
    QStringList res;

    while (!items.isEmpty()) {
        auto item = items.takeFirst();
        auto of = QString("%1_%2_%3_%4_ori.jpg").arg(pcbNumber).arg(isTop?"t":"b").arg(item->index).arg(item->nType);
        auto f = dataPath + "/" + of;
        if(workmode == 1 | workmode == 3)
            item->saveOriImg(f);


        auto ofmark = QString("%1_%2_%3_%4_mark.jpg").arg(pcbNumber).arg(isTop?"t":"b").arg(item->index).arg(item->nType);
        auto fmark = dataPath + "/" + ofmark;
        if(workmode == 2 | workmode == 3)
            item->markImg(f,fmark);

        QStringList sigle;
        //添加文件名
        if(workmode == 1)
            sigle.append(of);
        else if(workmode = 2)
            sigle.append(ofmark);
        else
            sigle.append(of+'|'+ofmark);

        //添加板号
        sigle.append(this->pcbNumber);
        sigle.append(this->isTop?"T":"B");
        sigle.append(QString::number(item->index));
        sigle.append(QString::number(item->nType));

        //缺陷坐标 和 大小
        QString sizes,leftTop;
        for(auto it : item->rects)
        {
            leftTop += QString("%1*%2 | ").arg(it.x).arg(it.y);
            sizes += QString("%1*%2 | ").arg(it.width).arg(it.height);
        }
        sigle.append(leftTop);
        sigle.append(sizes);
        sigle.append(item->isTrueErr?"T":"F");

        res.append(sigle.join(","));
        delete item;
    }
    return qMakePair(dataPath,res);
}

bool ErrDataFileReader::checkErrDataFile(const QString &file)
{
    QFile f(file);
    if(f.open(QFile::ReadOnly))
    {
        QByteArray sign("Kaima pcb-avi-err File.");
        auto loadSign = f.read(sign.length()+2);
        f.close();
        auto b = loadSign.contains(sign);
        return b;
    }
    LOG() << f.errorString();
    return false;
}

bool ErrDataFileReader::blockCheckErrDataFile(const QString &file, bool &error,int timeoutS)
{
    QFile f(file);
    if(f.exists() == false) return false;

    int time = timeoutS;
    bool fOpenOk = false;
    while(time>0)
    {
        fOpenOk = f.open(QFile::ReadOnly);
        if(fOpenOk) break;
        QThread::msleep(1000);
        time--;
    }

    if(fOpenOk)
    {
        QByteArray sign("Kaima pcb-avi-err File.");
        auto loadSign = f.read(sign.length()+2);
        f.close();
        auto b = loadSign.contains(sign);
        error = false;
        return b;
    }
    error = true;
    LOG() << f.errorString();
    return false;
}

void ErrDataFileReader::errDataBaseSerialize()
{
    CArchive &ar = *m_arErr;
    // 文件头
    CString sSign("Kaima pcb-avi-err File.");
    {
        CString s;
        ar >> s;
        if( s != sSign )
        {
            hasError = true;
            return;
        }
    }

    UINT nCurVersion = 30, nVersionLoad;
    ar >> nVersionLoad;
    if( nCurVersion < nVersionLoad)
    {
        hasError = true;
        return;
    }
    BOOL bCompress;
    {
        if( nVersionLoad > 23 )
            ar >> bCompress;

        // 内容
        int nErrCount;
        ar >> nErrCount;
        //LOG() << "当前文件包含缺陷数量:" << nErrCount ;

        BYTE bHas;

        nItem *pItem;
        for(int iErr = 0; iErr < nErrCount; iErr++)
        {
            pItem = new nItem;
            pItem->index = iErr;
            ar >> pItem->point;
            if( nVersionLoad > 22 )
                ar >> pItem->ptImage;
            else
                pItem->ptImage = pItem->point;

            // Dib
            ar >> bHas;
            //LOG() << "缺陷图像:"  << (bool)bHas << " 是否压缩:" << (bool)bCompress ;
            if( bHas )
            {
                pItem->pDib = CreateIDib();
                if( bCompress )
                {
                    pItem->isSerializeJpg = pItem->pDib->SerializeJpg(ar);
                }
                else
                    pItem->pDib->Serialize(ar);
            }
            else
                pItem->pDib = nullptr;

            // TypeDib
            if( nVersionLoad > 8 )
            {
                ar >> bHas;
                if( bHas )
                {
                    pItem->pTypeDib = CreateIDib();// CreateINoPaintDib();
                    pItem->pTypeDib->Serialize(ar);
                }
                else
                    pItem->pTypeDib = nullptr;
            }

            int nRectCount;
            // rects
            ar >> nRectCount;
            //LOG() << "缺陷区域数量:"  << nRectCount ;
            if( nRectCount > 0 )
            {
                //              pItem->pRcs = new CRectArray;
                //              pRects = pItem->pRcs;
                //              pRects->SetSize( nRectCount );
                CRect rc;
                for(int iRect = 0; iRect < nRectCount; iRect++)
                {
                    ar >> rc;
                    cv::Rect cvrc(rc.TopLeft().x,rc.TopLeft().y,rc.Width(),rc.Height());
                    pItem->rects.append(cvrc);
                    //LOG() << "区域编号:" << iRect << "位置:" << QRect(rc.TopLeft().x,rc.TopLeft().y,rc.Width(),rc.Height());
                }
            }
            ar >> pItem->nType;
            items.append(pItem);
        }

        // 统计
        int nCount = 0;
        if( nVersionLoad > 25 )
        {
            ar >> nCount;
            //            //LOG() << "统计:"  << nCount;
        }
        else
        {
            if( nVersionLoad < 2 )
                nCount = 12;
            else if( nVersionLoad < 3 )
                nCount = 13;
            else if( nVersionLoad < 5 )
                nCount = 14;
            else if( nVersionLoad < 6 )
                nCount = 15;
            else if( nVersionLoad < 8 )
                nCount = 16;
            else if( nVersionLoad < 10 )
                nCount = 27;
            else if( nVersionLoad < 11 )
                nCount = 28;
            else if( nVersionLoad < 12 )
                nCount = 29;
            else if( nVersionLoad < 14 )
                nCount = 30;
            else if( nVersionLoad < 15 )
                nCount = 31;
            else if( nVersionLoad < 16 )
                nCount = 32;
            else if( nVersionLoad < 17 )
                nCount = 33;
            else if( nVersionLoad < 18 )
                nCount = 34;
            else if( nVersionLoad < 19 )
                nCount = 35;
            else if( nVersionLoad < 20 )
                nCount = 36;
            else if( nVersionLoad < 23 )
                nCount = 37;
            else
                nCount = 38;
        }
        int typex;
        for(int iType = 0; iType < nCount; iType++)
        {
            ar >>typex;// m_aTotals[ iType ];
            //            //LOG() << "iType index " << iType << " value " <<typex;
        }
        float             m_fCarAngle; // 检修用的旋转角度
        CSize             m_szCarOffset;
        CSize             m_szAdjustOffset;
        float             m_fPrecision;
        int               m_iScanCol;
        BOOL              m_bPcbTop;
        BOOL              m_bTimeOut;
        BOOL              m_bTryTest;
        CString              m_sPlNo;
        int               m_nPcbNo;

        // 附带信息
        if( nVersionLoad > 0 )
        {
            ar >> m_szAdjustOffset;
            if( nVersionLoad > 12 )
                ar >> m_fPrecision;
            else
                m_fPrecision = 0;
            ar >> m_iScanCol;
            if( nVersionLoad > 3 )
                ar >> m_sPlNo;
            else
                m_sPlNo = "";
            ar >> m_nPcbNo;
            ar >> m_bPcbTop;
            ar >> m_bTimeOut;

            isTop = (bool)m_bPcbTop;
            pcbNumber = QString::number(m_nPcbNo);

            //            //LOG() <<  "附加信息 "<< "m_szAdjustOffset " << m_szAdjustOffset.cx << "x" << m_szAdjustOffset.cy
            //                   << " m_fPrecision " << m_fPrecision << " m_iScanCol " << m_iScanCol
            //                   << " m_sPlNo " << m_sPlNo << " m_nPcbNo " << m_nPcbNo
            //                   << " m_bPcbTop " << (bool)m_bPcbTop << " m_bTimeOut " <<(bool)m_bTimeOut  ;
        }
        else
        {
            m_szAdjustOffset = CSize(0, 0);
            m_fPrecision = 0;
            m_iScanCol = -1;
            m_sPlNo = "";
            m_nPcbNo = 0;
            m_bPcbTop = true;
            m_bTimeOut = false;
        }
        if( nVersionLoad > 6 )
            ar >> m_bTryTest;
        else
            m_bTryTest = false;

        //        //LOG() <<  "m_bTryTest "<< (bool)m_bTryTest ;
        if( nVersionLoad > 21 )
        {
            ar >> m_fCarAngle;
            ar >> m_szCarOffset;
        }
        else
        {
            m_fCarAngle = 0;
            m_szCarOffset = CSize(0, 0);
        }

        //        //LOG() <<  "m_fCarAngle "<< m_fCarAngle << " m_szCarOffset " << m_szCarOffset.cx << "x" << m_szCarOffset.cy ;

        CString              m_sJob;
        BYTE              m_nPlaceType;
        if( nVersionLoad > 26 )
        {
            ar >> m_sJob;
            ar >> m_nPlaceType;
        }
        //        //LOG() <<  "m_sJob "<< m_sJob << " m_nPlaceType " << m_nPlaceType ;

        int               m_iUnitPadErr;
        if( nVersionLoad > 24 )
        {
            int nUnitPadCount;
            ar >> nUnitPadCount;

            //            //LOG() <<  "nUnitPadCount "<< nUnitPadCount  ;

            BYTE tmp;
            //           m_aUnitPadResults.SetSize( nUnitPadCount );
            for(int iUnitPad = 0; iUnitPad < nUnitPadCount; iUnitPad++)
            {
                ar >> tmp;

                //                //LOG() <<  "index "<< iUnitPad << " value "<< tmp;
            }
            ar >> m_iUnitPadErr;
            //            //LOG() <<  "m_iUnitPadErr "<< m_iUnitPadErr  ;
        }
        else
        {
            //           m_aUnitPadResults.RemoveAll();
            m_iUnitPadErr = -1;
        }
        CString              m_sDecode;
        if( nVersionLoad > 29 )
            ar >> m_sDecode;

        //        //LOG() <<  "m_sDecode "<< m_sDecode  ;

        // 附带多片
        if( nVersionLoad > 20 )
        {
            int nMultiTest;
            ar >> nMultiTest;
            //            //LOG() <<  "附带多片 nMultiTest  "<< nMultiTest  ;
            //CErrDataBase* pErrData;
            for(int i = 0; i < nMultiTest; i++)
            {
                //pErrData = CreateErrData();
                //m_aMultiTestErrDatas.Add( pErrData );

                //                //LOG() <<  "附带多片 index ------------------------------------- "<< i  ;
                if( !CErrDataBase_Serialize(ar, bCompress))
                {
                    hasError = true;
                    return;
                }
            }
        }

        int m_iMultiTest;
        if( nVersionLoad > 28 )
            ar >> m_iMultiTest;

        //        //LOG() <<  "m_iMultiTest "<< m_iMultiTest ;

        if( nVersionLoad > 27 )
        {
            double f;
            int nDetailCount;
            ar >> nDetailCount;
            //           m_aDetailLineWidths.SetSize( nDetailCount );
            //            //LOG() <<  "nDetailCount "<< nDetailCount ;
            for(int iDetail = 0; iDetail < nDetailCount; iDetail++)
            {
                ar >> f;
                //              m_aDetailLineWidths[ iDetail ] = f;
                //                //LOG() <<  "index "<< iDetail << " value "<< f ;
            }
        }
    }
}

void ErrDataFileReader::errTrueSerialize()
{    
    if(m_arTrue == nullptr) return;

    CArchive &ar = *m_arTrue;
    UINT nCurVersion = 10, nVersionLoad;
    ar >> nVersionLoad;

    if( nCurVersion < nVersionLoad)
    {
        return;
    }

    int size = -1;
    ar >> size;

    int idx = -1;
    for(int i=0;i<size;i++)
    {
        ar >> idx;
        if(items.size() > idx)
        {
            items.at(idx)->isTrueErr = true;
        }
    }
}
